package com.songcha.library_base.base

import android.os.Bundle
import android.view.*
import android.widget.Button
import android.widget.FrameLayout
import android.widget.TextView
import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.fragment.app.Fragment
import com.songcha.library_base.R
import com.songcha.library_base.config.SizeConfig
import com.songcha.library_common.ui.dialog.LoadingDialog
import com.songcha.library_common.util.ColorUtil
import java.lang.ref.WeakReference


abstract class BaseFragment : Fragment(), IBasePage {
    private var mViewStubLoading: ViewStub?=null
    private var mViewLoading:View?=null

    private var mViewStubError: ViewStub?=null
    private var mViewError:View?=null

    private var mViewStubNoData: ViewStub?=null
    private var mViewNoData:View?=null

    private var mViewStubTimeout: ViewStub?=null
    private var mViewTimeout:View?=null

    private var mViewStubNoNetwork: ViewStub?=null
    private var mViewNoNetwork:View?=null

    private var mViewStubConnectError:ViewStub?=null
    private var mViewConnectError:View?=null

    private var mBtnRetry: Button?=null

    private var mLoadingDialog: LoadingDialog?=null

    protected var mRootView:View?=null

    private var mIsApplyWindowInsetsCall=false

    var TAG=""


    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val rootView=initOnCreateView()
        if(rootView!=null)
            return rootView
        else
            return super.onCreateView(inflater, container, savedInstanceState)
    }

    open fun initOnCreateView():View?{
        var rootView=getRootView()?:LayoutInflater.from(requireContext()).inflate(getLayoutId(),null)
        if(rootView!=null){
            mRootView=rootView
            mRootView!!.post{
                onRootViewPost()
            }
            return initLoad(rootView)
        }
        else
            return null
    }

    override fun onRootViewPost() {

    }


    override fun getRootView():View?{
        return null
    }

    override fun getLayoutId():Int{
        return 0
    }

    protected open fun setLoadingDialogCancelable(cancelable:Boolean){
        mLoadingDialog?.setCancelable(cancelable)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initView(savedInstanceState)
    }

    //onApplyWindowInsetsCall of fragment must invoke by activity,
    //because fragment may not load when activity load then will invoke before fragment load
    override fun onApplyWindowInsetsCall(v: View, insets: WindowInsetsCompat){

    }

    override fun showLoadingDialog(cancelable: Boolean){
        mLoadingDialog?.let {
            if(!cancelable){
                it.setCancelable(false)
                it.setCanceledOnTouchOutside(false)
            }
            it.show()
        }
    }

    override fun hideLoadingDialog(){
        mLoadingDialog?.let {
            it.dismiss()
            it.setProgress(0)
        }
    }

    override fun setLoadingDialogProgress(progress: Int) {
        mLoadingDialog?.setProgress(progress)
    }


    override fun initView(savedInstanceState: Bundle?) {
        if(isNeedShowLoadingDialog()) mLoadingDialog= LoadingDialog(requireContext())
    }


    override fun isNeedShowLoadingDialog():Boolean{
        return false
    }

    override fun isNeedShowLoad():Boolean{
        return false
    }

    open fun getLoadingLayoutId():Int{
        return R.layout.base_stub_loading
    }
    override fun getLoadErrorLayoutId():Int{
        return R.layout.base_stub_error
    }
    override fun getLoadNoDataLayoutId():Int{
        return R.layout.base_stub_nodata
    }
    override fun getLoadTimeoutLayoutId():Int{
        return R.layout.base_stub_timeout
    }
    override fun getLoadNoNetworkLayoutId():Int{
        return R.layout.base_stub_no_network
    }

    override fun getLoadConnectErrorLayoutId():Int{
        return R.layout.base_stub_connect_error
    }

    override fun getLoadErrorTip(): String {
        return "加载失败"
    }

    override fun getLoadNoDataTip(): String {
        return "没有数据"
    }

    override fun getLoadTimeOutTip(): String {
        return "网络连接超时"
    }

    override fun getLoadNoNetworkTip(): String {
        return "请检查网络设置"
    }

    override fun getLoadConnectErrorTip(): String {
        return "网络连接失败"
    }

    private fun calculateLoadViewTopMargin():Int{
        var topMargin=getLoadViewTopMargin()
        return topMargin
    }

    protected open fun getLoadViewTopMargin():Int{
        return 0
    }

    protected open fun initLoad(rootView:View):View{
        if(!isNeedShowLoad()) return rootView
        val frameLayout=FrameLayout(requireContext())
        val frameLayoutLp=ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
        frameLayout.layoutParams=frameLayoutLp

        val vsLp=FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)
        vsLp.topMargin=calculateLoadViewTopMargin()

        mViewStubLoading=ViewStub(requireContext())
        mViewStubLoading!!.layoutResource=getLoadingLayoutId()
        mViewStubLoading!!.layoutParams=vsLp

        mViewStubError=ViewStub(requireContext())
        mViewStubError!!.layoutResource=getLoadErrorLayoutId()
        mViewStubError!!.layoutParams=vsLp

        mViewStubNoData=ViewStub(requireContext())
        mViewStubNoData!!.layoutResource=getLoadNoDataLayoutId()
        mViewStubNoData!!.layoutParams=vsLp

        mViewStubTimeout=ViewStub(requireContext())
        mViewStubTimeout!!.layoutResource=getLoadTimeoutLayoutId()
        mViewStubTimeout!!.layoutParams=vsLp

        mViewStubNoNetwork=ViewStub(requireContext())
        mViewStubNoNetwork!!.layoutResource=getLoadNoNetworkLayoutId()
        mViewStubNoNetwork!!.layoutParams=vsLp

        mViewStubConnectError=ViewStub(requireContext())
        mViewStubConnectError!!.layoutResource=getLoadConnectErrorLayoutId()
        mViewStubConnectError!!.layoutParams=vsLp

        frameLayout.addView(rootView)
        frameLayout.addView(mViewStubLoading)
        frameLayout.addView(mViewStubError)
        frameLayout.addView(mViewStubNoData)
        frameLayout.addView(mViewStubTimeout)
        frameLayout.addView(mViewStubNoNetwork)
        frameLayout.addView(mViewStubConnectError)

        return frameLayout
    }


    private fun initBtnRetry(view:View){
        mBtnRetry=view.findViewById(R.id.btn_retry)
        mBtnRetry?.let {
            if(showRetryBtn()){
                it.setOnClickListener {
                    onRetry()
                }
            }else{
                it.visibility=View.GONE
            }
        }

    }

    protected open fun showRetryBtn():Boolean{
        return true
    }

    override fun getLoadBackgroundColor():Int{
        return ColorUtil.getResourceColor(requireContext(), com.songcha.library_common.R.color.page_background)
    }

    override fun onLoadErrorInflate(view: View) {

    }

    override fun onLoadNoDataInflate(view: View) {

    }

    override fun onLoadNoNetworkInflate(view: View) {

    }

    override fun onLoadTimeoutInflate(view: View) {

    }

    override fun onLoadConnectErrorInflate(view: View) {

    }

    override fun onLoadSuccess() {
        if(mViewLoading!=null)mViewLoading!!.visibility=View.GONE
        if(mViewError!=null)mViewError!!.visibility=View.GONE
        if(mViewNoData!=null)mViewNoData!!.visibility=View.GONE
        if(mViewTimeout!=null)mViewTimeout!!.visibility=View.GONE
        if(mViewNoNetwork!=null)mViewNoNetwork!!.visibility=View.GONE
    }

    override fun onLoading() {
        if(mViewStubLoading!=null){
            (mViewStubLoading!!.layoutParams as FrameLayout.LayoutParams).topMargin=calculateLoadViewTopMargin()
            if(mViewLoading==null){
                mViewLoading=mViewStubLoading!!.inflate()
            }else{
                mViewLoading!!.visibility=View.VISIBLE
            }
            mViewLoading!!.setBackgroundColor(getLoadBackgroundColor())
            if(mViewError!=null)mViewError!!.visibility=View.GONE
            if(mViewNoData!=null)mViewNoData!!.visibility=View.GONE
            if(mViewTimeout!=null)mViewTimeout!!.visibility=View.GONE
            if(mViewNoNetwork!=null)mViewNoNetwork!!.visibility=View.GONE

        }

    }


    override fun onLoadError(e: Throwable) {
        if(mViewStubError!=null){
            (mViewStubError!!.layoutParams as FrameLayout.LayoutParams).topMargin=calculateLoadViewTopMargin()
            if(mViewError==null){
                mViewError=mViewStubError!!.inflate()
                mViewError!!.findViewById<TextView>(R.id.tv_msg).text=getLoadErrorTip()
                onLoadErrorInflate(mViewError!!)
            }else{
                mViewError!!.visibility=View.VISIBLE
            }
            mViewError!!.setBackgroundColor(getLoadBackgroundColor())
            if(mViewLoading!=null)mViewLoading!!.visibility=View.GONE
            if(mViewNoData!=null)mViewNoData!!.visibility=View.GONE
            if(mViewTimeout!=null)mViewTimeout!!.visibility=View.GONE
            if(mViewNoNetwork!=null)mViewNoNetwork!!.visibility=View.GONE
            if(mViewConnectError!=null)mViewConnectError!!.visibility=View.GONE

            initBtnRetry(mViewError!!)
        }
    }

    override fun onLoadNoNetwork() {
        if(mViewStubNoNetwork!=null){
            (mViewStubNoNetwork!!.layoutParams as FrameLayout.LayoutParams).topMargin=calculateLoadViewTopMargin()
            if(mViewNoNetwork==null){
                mViewNoNetwork=mViewStubNoNetwork!!.inflate()
                mViewNoNetwork!!.findViewById<TextView>(R.id.tv_msg).text=getLoadNoNetworkTip()
                onLoadNoNetworkInflate(mViewNoNetwork!!)
            }else{
                mViewNoNetwork!!.visibility=View.VISIBLE
            }
            mViewNoNetwork!!.setBackgroundColor(getLoadBackgroundColor())
            if(mViewLoading!=null)mViewLoading!!.visibility=View.GONE
            if(mViewNoData!=null)mViewNoData!!.visibility=View.GONE
            if(mViewTimeout!=null)mViewTimeout!!.visibility=View.GONE
            if(mViewError!=null)mViewError!!.visibility=View.GONE
            if(mViewConnectError!=null)mViewConnectError!!.visibility=View.GONE

            initBtnRetry(mViewNoNetwork!!)
        }
    }

    override fun onLoadConnectError() {
        if(mViewStubConnectError!=null){
            (mViewStubConnectError!!.layoutParams as FrameLayout.LayoutParams).topMargin=calculateLoadViewTopMargin()
            if(mViewConnectError==null){
                mViewConnectError=mViewStubConnectError!!.inflate()
                mViewConnectError!!.findViewById<TextView>(R.id.tv_msg).text=getLoadConnectErrorTip()
                onLoadConnectErrorInflate(mViewConnectError!!)
            }else{
                mViewConnectError!!.visibility=View.VISIBLE
            }
            mViewConnectError!!.setBackgroundColor(getLoadBackgroundColor())
            if(mViewLoading!=null)mViewLoading!!.visibility=View.GONE
            if(mViewNoData!=null)mViewNoData!!.visibility=View.GONE
            if(mViewTimeout!=null)mViewTimeout!!.visibility=View.GONE
            if(mViewError!=null)mViewError!!.visibility=View.GONE
            if(mViewNoNetwork!=null)mViewNoNetwork!!.visibility=View.GONE

            initBtnRetry(mViewConnectError!!)
        }
    }

    override fun onLoadTimeOut() {
        if(mViewStubTimeout!=null){
            (mViewStubTimeout!!.layoutParams as FrameLayout.LayoutParams).topMargin=calculateLoadViewTopMargin()
            if(mViewTimeout==null){
                mViewTimeout=mViewStubTimeout!!.inflate()
                mViewTimeout!!.findViewById<TextView>(R.id.tv_msg).text=getLoadTimeOutTip()
                onLoadTimeoutInflate(mViewTimeout!!)
            }else{
                mViewTimeout!!.visibility=View.VISIBLE
            }
            mViewTimeout!!.setBackgroundColor(getLoadBackgroundColor())
            if(mViewLoading!=null)mViewLoading!!.visibility=View.GONE
            if(mViewNoData!=null)mViewNoData!!.visibility=View.GONE
            if(mViewNoNetwork!=null)mViewNoNetwork!!.visibility=View.GONE
            if(mViewError!=null)mViewError!!.visibility=View.GONE
            if(mViewConnectError!=null)mViewConnectError!!.visibility=View.GONE

            initBtnRetry(mViewTimeout!!)
        }
    }

    override fun onLoadNoData() {
        if(mViewStubNoData!=null){
            (mViewStubNoData!!.layoutParams as FrameLayout.LayoutParams).topMargin=calculateLoadViewTopMargin()
            if(mViewNoData==null){
                mViewNoData=mViewStubNoData!!.inflate()
                mViewNoData!!.findViewById<TextView>(R.id.tv_msg).text=getLoadNoDataTip()
                onLoadNoDataInflate(mViewNoData!!)
            }else{
                mViewNoData!!.visibility=View.VISIBLE
            }
            mViewNoData!!.setBackgroundColor(getLoadBackgroundColor())
            if(mViewLoading!=null)mViewLoading!!.visibility=View.GONE
            if(mViewTimeout!=null)mViewTimeout!!.visibility=View.GONE
            if(mViewNoNetwork!=null)mViewNoNetwork!!.visibility=View.GONE
            if(mViewError!=null)mViewError!!.visibility=View.GONE
            if(mViewConnectError!=null)mViewConnectError!!.visibility=View.GONE

            initBtnRetry(mViewNoData!!)
        }
    }

    protected open fun onRetry() {
        //onLoading()
    }

   override fun isBaseOnWidth(): Boolean {
        return true
    }

    override fun getSizeInDp(): Float {
        return SizeConfig.SCREEN_WIDTH_DP
    }
}